﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Drawing;

namespace ReceiveGroupData
{
    /// <summary>
    /// 传感器对象
    /// </summary>
    #region //传感器
    public class Sensor
    {
        /// <summary>
        ///传感器名称 
        /// </summary>
        public string strName = string.Empty;
        /// <summary>
        /// 传感器ID
        /// </summary>
        public string strID = string.Empty;
        /// <summary>
        /// 传感器编号(0,1) 
        /// </summary>  
        public int iCode = 0;
        /// <summary>
        /// 标定波长
        /// </summary>
        public double dblBase = 0;
        /// <summary>
        /// 安装位置
        /// </summary> 
        public string strPosition = string.Empty;
        /// <summary>
        /// 传感器状态
        /// </summary>
        public bool bState = true;
    }
    #endregion

    /// <summary>
    /// 传感器组对象
    /// </summary>
    #region //传感器组
    public class LxGroup
    {
        /// <summary>
        /// 传感器1
        /// </summary>
        public Sensor sensor1 = new Sensor() { iCode = 0, bState = true };
        /// <summary>
        /// 传感器2
        /// </summary>
        public Sensor sensor2 = new Sensor() { iCode = 1, bState = true };
        /// <summary>
        /// 传感器组号
        /// </summary>
        public int iGroup = 0;
        /// <summary>
        ///处理主机编号
        /// </summary>
        public int iFbgaCode = 0;
        /// <summary>
        /// 轨道区间编号
        /// </summary>
        public int iZoneid = -1;
        /// <summary>
        /// 记录轴数
        /// </summary>
        public int iAxleNum = 0;
    }
    #endregion

    /// <summary>
    /// 区段对象
    /// </summary>
    #region//区段
    public class DGZone
    {
        /// <summary>
        /// 处理主机编号
        /// </summary>
        public int iFbgaCode = 0;
        /// <summary>
        /// 轨道区间最左端位置
        /// </summary>
        public int iLeft = 0;
        /// <summary>
        /// 轨道区间名称
        /// </summary>
        public string strName = string.Empty;
        /// <summary>
        /// 光带颜色画笔
        /// </summary>
        public Pen LightBlet = new Pen(SystemColors.GradientInactiveCaption, 2f);
        /// <summary>
        /// 区段传感器记轴信息描述
        /// </summary>
        public string strDescribe = string.Empty;

    }
    #endregion

    /// <summary>
    /// 屏幕绘制基本信息的类
    /// </summary>
    public class gState
    {
        /// <summary>
        /// 画笔
        /// </summary>
        public Pen pen = CGlobal.BasicPen;
        /// <summary>
        /// 文本
        /// </summary>
        public string strTxt = string.Empty;
        /// <summary>
        /// 是否需要重绘
        /// </summary>
        public bool isReDraw = false;
        /// <summary>
        /// 区段分组左端列表
        /// </summary>
        public List<string> cGroupL = new List<string>();
        /// <summary>
        /// 区段分组右端列表
        /// </summary>
        public List<string> cGroupR = new List<string>();
        /// <summary>
        /// 区段的最左端值
        /// </summary>
        public int mLeft = 0;
        /// <summary>
        /// 要绘制的基本数据信息
        /// </summary>
        /// <param name="p">绘图的画笔</param>
        /// <param name="str">绘制的文本</param>
        /// <param name="b">是否需要绘图</param>
        public gState(Pen p, string str, bool b)
        {
            pen = p;
            strTxt = str;
            isReDraw = b;
        }

        public gState()
        {
            //……
        }
    }

    public static class CGlobal
    {

        private static bool _IGIF = false;
        public static bool IsGetIniFile()
        {
            bool ret = true;

            //……………………

            _IGIF = ret;
            return ret;
        }

        public static bool IsInitlizedFile()
        {
            bool ret = false;
            if (!_IGIF) return ret;

            //………………
            ret = true;
            return ret;
        }

        private static Queue<byte[]> RecData = new Queue<byte[]>();
        public static Mutex mutex = new Mutex();
        public static void AddRecData(byte[] bytes)
        {
            mutex.WaitOne();
            try
            {
                if (RecData.Count > 1999)
                    RecData.Dequeue();
                RecData.Enqueue(bytes);
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.StackTrace + ":" + ex.Message); }
            mutex.ReleaseMutex();
        }
        public static int GetWaitCount()
        {
            return RecData.Count;
        }
        private static CRC32 _crc = new CRC32();
        public static Dictionary<string, LxGroup> GroupDic = new Dictionary<string, LxGroup>();
        public static List<string> AvailableQuDuan = new List<string>();
        public static Dictionary<string, gState> DrawStrDic = new Dictionary<string, gState>();
        
        public static Pen BasicPen { get { return new Pen(Color.FromArgb(0x4F, 0x81, 0xBD), 1.0f); } }
        public static Pen WhiteBelt { get { return new Pen(Color.WhiteSmoke, 1.0f); } }
        public static Pen RedBelt { get { return new Pen(Color.Red, 1.0f); } }
        public static Pen NegativePen { get { return new Pen(Color.Yellow, 1.0f); } }

        public static Pen DifBasic { get { return new Pen(Color.FromArgb(0x4F, 0x81, 0xBD), 2.0f); } }
        public static Pen DifWhite { get { return new Pen(Color.WhiteSmoke, 2.0f); } }
        public static Pen DifRed { get { return new Pen(Color.Red, 2.0f); } }
        public static Pen DifNegative { get { return new Pen(Color.Yellow, 2.0f); } }

        public static void unPack(int iPos, ref List<DGZone> dgZoneList)
        {
            dgZoneList = new List<DGZone>();
            try
            {
                int iCount = iPos > CGlobal.GetWaitCount() ? CGlobal.GetWaitCount() : iPos;
                List<byte[]> tmp = new List<byte[]>();
                mutex.WaitOne();
                for (int i = 0; i < iPos; i++)
                {
                    tmp.Add(RecData.Dequeue());
                }
                mutex.ReleaseMutex();
                foreach (byte[] bytes in tmp)
                {
                    if (bytes == null) return;
                    //帧长度不小于9个字节
                    if (bytes.Length < 9) return;
                    //CRC校验正确
                    if (_crc.getCRC32(bytes) == (int)(BitConverter.ToInt16(bytes, bytes.Length - 2))) return;
                    int i = 0;
                    //帧头4个来连续的0xA5
                    for (; i < 4; i++)
                    {
                        if (bytes[i] != 0xA5) return;
                    }
                    //帧类型0x06
                    if (bytes[4] != 0x06) return;
                    //有效数据内容长度
                    int len = (int)(bytes[5] << 8 | bytes[6]);
                    if (len != bytes.Length - 9 || len == 0) return;
                    //主机编号
                    int iFbgaCode = (int)bytes[7];
                    //有效传感器分组数
                    int tCount = (int)bytes[8];
                    i = 9;
                    if (tCount > 0 && (tCount <= GroupDic.Count))
                    {
                        for (; i < 9 + 3 * tCount; )
                        {
                            string igroup = bytes[i++].ToString();
                            if (GroupDic.ContainsKey(igroup))
                            {
                                GroupDic[igroup].iFbgaCode = iFbgaCode;
                                GroupDic[igroup].iFbgaCode = iFbgaCode;
                                GroupDic[igroup].iAxleNum = (int)(BitConverter.ToInt16(bytes, i));
                                i += 2;
                            }
                        }
                    }
                    //故障分组计数
                    int gCount = (int)bytes[i++];
                    if (gCount > 0)
                    {
                        for (int j = i; i < j + 2 * gCount; )
                        {
                            string igroup = bytes[i++].ToString();
                            if (GroupDic.ContainsKey(igroup))
                            {
                                GroupDic[igroup].iFbgaCode = iFbgaCode;
                                switch (bytes[i++])
                                {
                                    case 0:
                                        GroupDic[igroup].sensor1.bState = GroupDic[igroup].sensor2.bState = false;
                                        break;
                                    case 1:
                                        GroupDic[igroup].sensor2.bState = false;
                                        break;
                                    case 2:
                                        GroupDic[igroup].sensor1.bState = false;
                                        break;
                                }
                            }
                        }
                    }
                }
                tmp.Clear();
                /*
                foreach (Quduan qd in DrawStrDic.Keys)
                {
                    //区段内是否有成对的分组
                    bool qdstate = true;
                    if ((DrawStrDic[qd].cGroupL.Count > 0) && (DrawStrDic[qd].cGroupR.Count > 0))
                    {
                        int nleft = 0;
                        string strtmp = string.Format("区段:{0}  ", qd.name);
                        DrawStrDic[qd].cGroupL.Sort();
                        foreach (string num in DrawStrDic[qd].cGroupL)
                        {
                            if (GroupDic.ContainsKey(num))
                            {
                                if (!GroupDic[num].sensor1.bState || !GroupDic[num].sensor2.bState)
                                {
                                    strtmp += string.Format("点{0}传感器故障  ", num);
                                    qdstate = false;
                                    continue;
                                }
                                if (!qdstate) continue;
                                nleft += GroupDic[num].iAxleNum;
                                strtmp += string.Format("点{0}:{1}  ", num, GroupDic[num].iAxleNum);
                            }
                        }
                        int nright = 0;
                        DrawStrDic[qd].cGroupR.Sort();
                        foreach (string num in DrawStrDic[qd].cGroupR)
                        {
                            if (GroupDic.ContainsKey(num))
                            {
                                if (!GroupDic[num].sensor1.bState || !GroupDic[num].sensor2.bState)
                                {
                                    strtmp += string.Format("点{0}传感器故障  ", num);
                                    qdstate = false;
                                    continue;
                                }
                                if (!qdstate) continue;
                                nright += GroupDic[num].iAxleNum;
                                strtmp += string.Format("点{0}:{1}  ", num, GroupDic[num].iAxleNum);
                            }
                        }
                        //区段内有多少轴数
                        DGZone zone = new DGZone();
                        zone.iLeft = DrawStrDic[qd].mLeft;
                        zone.strName = qd.name;
                        if (!qdstate)
                        {
                            zone.LightBlet = CGlobal.DifBasic;
                            zone.strDescribe = strtmp;
                            dgZoneList.Add(zone);
                        }
                        else
                        {
                            zone.LightBlet = (nleft != nright) ? CGlobal.DifRed : CGlobal.DifBasic;
                            //zone.LightBlet = (nleft != nright) ? CGlobal.DifNegative : CGlobal.DifBasic;
                            zone.strDescribe = strtmp + string.Format("余数:{0}", Math.Abs(nleft - nright));
                            dgZoneList.Add(zone);
                        }
                    }
                }
                 * */
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.StackTrace + ":" + ex.Message);
            }
        }

        private static void getSwitchValues(List<byte> switchValue, ref List<DGZone> dgZoneList)
        {
            if (dgZoneList == null)
            {
                dgZoneList = new List<DGZone>();
                return;
            }
        }
    }
}
